package com.erpoa.service.impl;

import com.alibaba.fastjson.JSON;
import com.erpoa.annotation.DataBase;
import com.erpoa.constants.DataSourceNames;
import com.erpoa.entity.PackMessage;
import com.erpoa.entity.RecMatEntity;
import com.erpoa.mapper.GoodsOutMaterialMapper;
import com.erpoa.service.BatchUtilService;
import com.erpoa.service.FactoryUtilService;
import com.erpoa.service.GoodsOutMaterialService;
import com.erpoa.utils.BarcodeUtil;
import com.erpoa.utils.PDAException;
import com.erpoa.utils.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.UUID;

/**
 * @author chenjimin
 * @Title: GoodsOutMaterialServiceImpl
 * @ProjectName oaerp
 * @Description: TODO
 * @date 2020/9/2115:23
 */
@Service
public class GoodsOutMaterialServiceImpl implements GoodsOutMaterialService {
    private static final Logger logger = LoggerFactory.getLogger(GoodsOutMaterialServiceImpl.class);

    @Autowired
    private GoodsOutMaterialMapper goodsOutMaterialMapper;

    @Autowired
    private FactoryUtilService factoryUtilService;
    @Autowired
    private BatchUtilService batchUtilService;

    @Override
    @DataBase(DataSourceNames.DSX5)
    @Transactional()
    public List<RecMatEntity> functionGetMatRect(String hrno) {
        // 0、判断条码是否存在

        List<RecMatEntity> entityList = this.goodsOutMaterialMapper.selectRecMatExistFlagByhrno(hrno);
        if (StringUtil.isEmpty(entityList)) {
            throw new PDAException("当前用户：" + hrno + ",没有匹配到符合条件的数据，请切换一个账号重试！");
        }
        return entityList;
    }

    @Override
    @DataBase(DataSourceNames.DSX5)
    @Transactional()
    public List<RecMatEntity> getInventory(PackMessage packMessage) {
        List<RecMatEntity> recMatEntityList = this.goodsOutMaterialMapper.selectWareByFid(packMessage.getCrashLog());
        if (StringUtil.isEmpty(recMatEntityList)) {
            throw new PDAException("获取仓库，库位，库存失败！");
        }
        return recMatEntityList;
    }

    @Override
    @DataBase(DataSourceNames.DSX5)
    @Transactional(isolation = Isolation.SERIALIZABLE)
    public synchronized void functionSubOutMat(PackMessage packMessage) {
        RecMatEntity recMatEntity = JSON.parseObject(packMessage.getMessage(), RecMatEntity.class);
        String fId;
        // 查询erp库存
        HashMap wareTemp = this.goodsOutMaterialMapper.selectWareSEatByFid(recMatEntity.getfRecID());
        if (StringUtil.isEmpty(wareTemp)) {
            throw new PDAException("未查询到erp库存，请确认！");
        }
        String fWareCode = wareTemp.get("FWARECODE") == null ? "" : wareTemp.get("FWARECODE").toString();
        String fSeatCode = wareTemp.get("FSEATCODE") == null ? "" : wareTemp.get("FSEATCODE").toString();
        String stock = wareTemp.get("IMG10") == null ? "" : wareTemp.get("IMG10").toString();

        if (!fWareCode.equals("E1022") || !fSeatCode.equals("Q1022")) {
            // 判断若此时扫入的发料数量+中间表数量（同一料号，同一仓库库位）- 对应仓库库位的ERP库存\>0 则报错"ERP库存不足此笔发料”.liujiajie
            // 2018-11-30
            Double sumQty = this.goodsOutMaterialMapper.selectSumxQtyByparam(recMatEntity.getfMatCode(), recMatEntity.getfWareCode(), recMatEntity.getfSeatCode());
            if (recMatEntity.getfWeight() + sumQty - Double.valueOf(stock) > 0) {
                throw new PDAException("ERP库存不足此笔发料");
            }
        }
        // 0、判断料号是不相符 和重新组合条码
        if ("笔头".equals(recMatEntity.getfType())) {
            boolean flag = factoryUtilService.checkUserValid(packMessage.getJobnum());
            if (!flag) {
                throw new PDAException("交接人:" + packMessage.getJobnum() + "未在aooi040找到或已经离职！");
            }
            // 0-1判断料号是否相符
            int count = this.goodsOutMaterialMapper.countBaimamByParam(recMatEntity.getfVenderCode(), recMatEntity.getfModelNo(), recMatEntity.getfMatCode());
            if (count <= 0) {
                throw new PDAException("料号:" + recMatEntity.getfMatCode() + "不符,不能发料！");
            }
            // 0-2 重新组合条码
            recMatEntity.setfBarCode(BarcodeUtil.getNewBarcode(recMatEntity.getfBarCode()));
        } else {
            int count = this.goodsOutMaterialMapper.countBaimamByParamcolor(recMatEntity.getfVenderCode(),
                    recMatEntity.getfModelNo(), recMatEntity.getfMatCode(), recMatEntity.getfColor());
            if (count <= 0) {
                throw new PDAException("料号:" + recMatEntity.getfMatCode() + "不符,不能发料！");
            }
        }


        // 0 取该领料对应的工厂和车间编码
        HashMap ffwcodeTemp = this.goodsOutMaterialMapper.selectffwcodeByfrecid(recMatEntity.getfRecID());
        if (StringUtil.isEmpty(ffwcodeTemp)) {
            throw new PDAException("料号:" + recMatEntity.getfMatCode() + "存在更早批次，请重新选择!");
        }

        String fFactoryCode = ffwcodeTemp.get("FFACTORYCODE") == null ? "" : ffwcodeTemp.get("FFACTORYCODE").toString();
        String fWorkShopCode = ffwcodeTemp.get("FWORKSHOPCODE") == null ? "" : ffwcodeTemp.get("FWORKSHOPCODE").toString();

        // 1、判断是否为最早批次，可调拨量是否满足调拨申请量
        HashMap fbqdTemp = this.goodsOutMaterialMapper.selectFBQDByParam(recMatEntity.getfMatCode(), recMatEntity.getfVenderCode(),
                fFactoryCode, fWorkShopCode, recMatEntity.getfBarCode());
        if (StringUtil.isEmpty(fbqdTemp)) {
            throw new PDAException("料号:" + recMatEntity.getfMatCode() + ",该批次可调拨量为0或存在更早批次!");
        }
        // 同批次最早的条码号
        String barCode = fbqdTemp.get("FBARCODE") == null ? "" : fbqdTemp.get("FBARCODE").toString();
        // 条码所剩数量
        double fQty = fbqdTemp.get("FQTY") == null ? 0 : Double.parseDouble(fbqdTemp.get("FQTY").toString());
        // MG_BATCHMAT的fid
        String matID = fbqdTemp.get("FID") == null ? "" : fbqdTemp.get("FID").toString();

        // 2.判断生产时间是否在最小的生产日期7天内,笔头不做此校验
        if (!"笔头".equals(recMatEntity.getfType())) {
            int count = this.goodsOutMaterialMapper.selectFprdatediffdateByParam(recMatEntity.getfMatCode(),
                    recMatEntity.getfVenderCode(), fFactoryCode, fWorkShopCode, matID);
            if (count > 7) {
                throw new PDAException("料号:" + recMatEntity.getfMatCode() + "存在更早批次，请重新选择!");
            }
        }
        // 3、判断是否为最早批次，可调拨量是否满足调拨申请量
        double count = this.goodsOutMaterialMapper.selectbarcodeLasterByParam(recMatEntity.getfBarCode(), fFactoryCode, fWorkShopCode);
        if (count <= 0) {
            throw new PDAException("条码:" + recMatEntity.getfBarCode() + "不存在！");
        }
        // 1.判断已发量是否大于申请量
        HashMap fqpQtyTemp = this.goodsOutMaterialMapper.selectfqpQtyByrecId(recMatEntity.getfRecID());
        if (StringUtil.isEmpty(fqpQtyTemp)) {
            throw new PDAException("未查到数据，请确认！");
        }
        double diffqty = fqpQtyTemp.get("DIFFQTY") == null ? 0 : Double.parseDouble(fqpQtyTemp.get("DIFFQTY").toString());
        if (diffqty <= 0) {
            throw new PDAException("已发料量已大于申请数量");
        }
        double fRqsQty = fqpQtyTemp.get("FRQSQTY") == null ? 0 : Double.parseDouble(fqpQtyTemp.get("FRQSQTY").toString()); // 申请量
        double fRspQty = fqpQtyTemp.get("FRSPQTY") == null ? 0 : Double.parseDouble(fqpQtyTemp.get("FRSPQTY").toString()); // 实发量
        if (barCode == null || barCode.length() <= 0) {
            throw new PDAException("该批次可调拨量为0或存在更早批次，请重新扫描");
        }
        if (fQty < recMatEntity.getfWeight()) {
            throw new PDAException("剩余可发料量小于条码数量");
        }
        double originalQty = recMatEntity.getfWeight();// 原料数量
        float adjustQty = 0;//调整数量
        float difQty = 0; //差异数量
        if ("笔头".equals(recMatEntity.getfType())) {
            if (fRqsQty < (fRspQty + recMatEntity.getfWeight())) {
                throw new PDAException("此次发料会造成发料量大于申请量");
            }
            //大于0修改MES 领料发料,小于0修改中间表数量
            List<Float> flQty = batchUtilService.getErpMargin(recMatEntity, "批次发料");
            if (flQty != null && !flQty.isEmpty()) {
                difQty = flQty.get(0);
                adjustQty = flQty.get(1);
            } else {
                originalQty = recMatEntity.getfWeight();
            }

        }
        // 1 更新调拨表
        if ("笔头".equals(recMatEntity.getfType()) && difQty > 0 && adjustQty != 0) {
            int effectRows = this.goodsOutMaterialMapper.updateTranferMatByParam(adjustQty, packMessage.getUser().getsCode(), recMatEntity.getfVenderCode(), recMatEntity.getfRecID());
            if (effectRows <= 0) {
                throw new PDAException("更新领料表失败!");
            }
        } else {
            int effectRows = this.goodsOutMaterialMapper.updateTranferMatByParam(originalQty,
                    packMessage.getUser().getsCode(), recMatEntity.getfVenderCode(), recMatEntity.getfRecID());
            if (effectRows <= 0) {
                throw new PDAException("更新领料表失败!");
            }
        }
        fId = UUID.randomUUID().toString();
        // 2 插入调拨领退料明细
        if ("笔头".equals(recMatEntity.getfType())) {
            if (difQty > 0 && adjustQty != 0) {
                int updateNum = this.goodsOutMaterialMapper.insertDetailByParam(fId, adjustQty,
                        packMessage.getUser().getsCode(), packMessage.getJobnum(), recMatEntity.getfBarCode(),
                        recMatEntity.getfRecID());
                if (updateNum <= 0) {
                    throw new PDAException(recMatEntity.getfType() + ":" + recMatEntity.getfMatCode() + "发料失败!");
                }
            } else {
                int updateNum = this.goodsOutMaterialMapper.insertDetailByParam(fId, originalQty,
                        packMessage.getUser().getsCode(), packMessage.getJobnum(), recMatEntity.getfBarCode(),
                        recMatEntity.getfRecID());
                if (updateNum <= 0) {
                    throw new PDAException(recMatEntity.getfType() + ":" + recMatEntity.getfMatCode() + "发料失败!");
                }
            }
        } else {
            int updateNum = this.goodsOutMaterialMapper.insertMgDetailByParam(fId, originalQty,
                    packMessage.getUser().getsCode(), recMatEntity.getfBarCode(), recMatEntity.getfRecID());
            if (updateNum <= 0) {
                throw new PDAException(recMatEntity.getfType() + ":" + recMatEntity.getfMatCode() + "发料失败!");
            }
        }
        // 3 插入日志表 liujiajie 2018-11-12
        if (difQty < 0 && adjustQty != 0) {
            int insertNum1 = this.goodsOutMaterialMapper.insertX5LogByParam(adjustQty, packMessage.getUser().getsCode(),
                    recMatEntity.getfBarCode(), fId, recMatEntity.getfRecID());
            if (insertNum1 <= 0) {
                throw new PDAException("写入日志表失败!");
            }
        } else {

            int insertNum1 = this.goodsOutMaterialMapper.insertX5LogByParam(originalQty, packMessage.getUser().getsCode(),
                    recMatEntity.getfBarCode(), fId, recMatEntity.getfRecID());
            if (insertNum1 <= 0) {
                throw new PDAException("写入日志表失败!");
            }
        }

        // 3 插入中间表

        if (difQty < 0 && adjustQty != 0) {
            int insertNum2 = this.goodsOutMaterialMapper.insertX5ByParam(adjustQty, packMessage.getUser().getsCode(),
                    recMatEntity.getfBarCode(), fId, recMatEntity.getfRecID());
            if (insertNum2 <= 0) {
                throw new PDAException("写入中间表失败!");
            }
        } else {
            int insertNum2 = this.goodsOutMaterialMapper.insertX5ByParam(originalQty, packMessage.getUser().getsCode(),
                    recMatEntity.getfBarCode(), fId, recMatEntity.getfRecID());
            if (insertNum2 <= 0) {
                throw new PDAException("写入中间表失败!");
            }
        }
        // 3更新收料明细表
        int effectRowNum = this.goodsOutMaterialMapper.updateBatchMatByParam(originalQty, matID);
        if (effectRowNum <= 0) {
            throw new PDAException("更新批次条码数据失败!");
        }
        // 记录每次更新的批次发料数量
        if (difQty < 0 && adjustQty != 0) {
            int recordCount = this.goodsOutMaterialMapper.insertBatchMatByParam(UUID.randomUUID().toString(), adjustQty,
                    packMessage.getUser().getsCode(), recMatEntity.getfType(), matID);
            if (recordCount <= 0) {
                throw new PDAException("插入批次库存记录的数据失败!");
            }
        } else {
            int recordCount = this.goodsOutMaterialMapper.insertBatchMatByParam(UUID.randomUUID().toString(), originalQty,
                    packMessage.getUser().getsCode(), recMatEntity.getfType(), matID);
            if (recordCount <= 0) {
                throw new PDAException("插入批次库存记录的数据失败!");
            }
        }
    }
}
